<?php
namespace App\Components\Admin;

use App\Models\System\SystemMenu;
use App\Models\System\SystemUser;

class Menu
{
    public static function treeFilter(array $tree, int $status = 1): array
    {
        foreach ($tree as $k => $v) {
            if (isset($v['children'][0])) {
                $v['children'] = self::treeFilter($v['children'], $status);
            } else {
                if (!isset($v['status']) || $v['status'] != $status) {
                    unset($tree[$k]);
                    continue;
                }
            }

            if (isset($v['children'])) {
                $v['children'] = array_values($v['children']);
                if (!isset($v['children'][0])) {
                    unset($v['children']);

                    if (!isset($v['status']) || $v['status'] != $status) {
                        unset($tree[$k]);
                        continue;
                    }
                }
            }

            $tree[$k] = $v;
        }
        return $tree;
    }

    public static function currentMenu(): array
    {
        $userId = SystemUser::getIdByToken();
        if ($userId <= 0) {
            return [];
        }

        $adminPattern = Router::getCurrentRequestControllerInfo();
        if (!isset($adminPattern[2]) || isset($adminPattern[3])) {
            return [];
        }

        $menuRs = SystemMenu::userMenu($userId);
        $menuRs = self::isCurrentProcess($menuRs, $adminPattern[0]);
        $isCurrent = false;
        foreach ($menuRs as $v) {
            if (isset($v['current']) && $v['current'] == true) {
                $isCurrent = true;
                break;
            }
        }
        $cookieKey = strtoupper($_ENV['app_name']) . '_MENULINK';
        if ($isCurrent === true) {
            setcookie($cookieKey, $adminPattern[0], time() + 7200, '/', '', false, true);
        } else {
            $menuLink = $_COOKIE[$cookieKey] ?? (Router::URL_PREFIX . '/index/index');
            $menuRs = self::isCurrentProcess($menuRs, $menuLink);
        }
        unset($isCurrent, $cookieKey);
        $menuRs = self::processUrl($menuRs);
        $menuRs = self::fillRootUrl($menuRs);
        $menuRs = self::processInvalid($menuRs);
        return $menuRs;
    }

    private static function isCurrentProcess(array $tree, string $url): array
    {
        foreach ($tree as $k => $v) {
            if (isset($v['children'])) {
                $tree[$k]['children'] = self::isCurrentProcess($v['children'], $url);
                $isCurrent = false;
                foreach ($tree[$k]['children'] as $v1) {
                    if (isset($v1['current']) && $v1['current'] == true) {
                        $isCurrent = true;
                        break;
                    }
                }
                if ($isCurrent == true) {
                    $tree[$k]['current'] = true;
                    break;
                }
            } else {
                if ($v['node'] == $url) {
                    $tree[$k]['current'] = true;
                    break;
                }
            }
        }

        return $tree;
    }

    private static function processUrl(array $tree): array
    {
        foreach ($tree as $k => $v) {
            $tree[$k]['url'] = $v['node'];
            if ($v['node'] != '#' && $v['parameter'] != '') {
                $tree[$k]['url'] .= '?' . $v['parameter'];
            }
            unset($tree[$k]['node'], $tree[$k]['parameter']);

            if (isset($v['children'])) {
                $tree[$k]['children'] = self::processUrl($v['children']);
            }
        }

        return $tree;
    }

    private static function processInvalid(array $tree): array
    {
        foreach ($tree as $k => $v) {
            if (!isset($v['current']) || $v['current'] != true) {
                unset($tree[$k]['children']);
            }
        }
        return $tree;
    }

    private static function fillRootUrl(array $tree): array
    {
        foreach ($tree as $k => $v) {
            if ($v['url'] != '#') {
                continue;
            }
            if (isset($v['children'])) {
                foreach ($v['children'] as $v1) {
                    if (isset($v1['children'])) {
                        foreach ($v1['children'] as $v2) {
                            if (isset($v2['children'])) {
                                foreach ($v2['children'] as $v3) {
                                    if ($v3['url'] == '#') {
                                        continue;
                                    }
                                    $tree[$k]['url'] = $v3['url'];
                                    break 3;
                                }
                            } else {
                                if ($v2['url'] == '#') {
                                    continue;
                                }
                                $tree[$k]['url'] = $v2['url'];
                                break 2;
                            }
                        }
                    } else {
                        if ($v1['url'] == '#') {
                            continue;
                        }
                        $tree[$k]['url'] = $v1['url'];
                        break;
                    }
                }
            }
        }

        return $tree;
    }
}
